package format

import (
	"encoding/json"
	"fmt"
	"net/http"

	"github.com/gin-gonic/gin"
)

func NewResponseJson(ctx *gin.Context) *responseJson {
	return &responseJson{
		context: ctx,
	}
}

type responseJson struct {
	context *gin.Context
}

func (r *responseJson) SetHeader(key, value string) *responseJson {
	r.context.Writer.Header().Set(key, value)
	return r
}

func (r *responseJson) Success(data interface{}) {
	r.context.JSON(http.StatusOK, ResponseData{
		Success: true,
		Code:    CodeSuccess,
		Msg:     CodeSuccess.Msg(),
		Data:    data,
	})
}

func (r *responseJson) Error(errorCode ResCode, params ...interface{}) {
	result := ResponseData{
		Success: false,
		Code:    errorCode,
		Msg:     errorCode.Msg(),
		Data:    params,
	}
	r.context.Abort()
	r.context.JSON(http.StatusOK, result)
}

func (r *responseJson) ErrorWithMsg(errorCode ResCode, params ...interface{}) {
	result := ResponseData{
		Success: false,
		Code:    errorCode,
		Msg:     params,
		Data:    nil,
	}
	r.context.Abort()
	r.context.JSON(http.StatusOK, result)
}

func (r *responseJson) Download(filename, path string) {
	r.SetHeader("Content-Disposition", fmt.Sprintf("attachment; filename=%s", filename))
	r.SetHeader("Content-Type", "application/octet-stream")
	r.context.File(path)
}

type ResponseData struct {
	Code    ResCode     `json:"code"`
	Msg     interface{} `json:"message"`
	Data    interface{} `json:"data"`
	Success bool        `json:"success"`
}

func NewWSResponse() *wsresponse {
	return &wsresponse{}
}

type wsresponse struct {
}

func (w *wsresponse) Success(data interface{}) *[]byte {
	result := ResponseData{
		Success: true,
		Code:    CodeSuccess,
		Msg:     CodeSuccess.Msg(),
		Data:    data,
	}
	rpacket, _ := json.Marshal(result)
	return &rpacket
}

func (w *wsresponse) Error(errorCode ResCode, params ...interface{}) *[]byte {
	result := ResponseData{
		Success: false,
		Code:    errorCode,
		Msg:     errorCode.Msg(),
		Data:    params,
	}
	rpacket, _ := json.Marshal(result)
	return &rpacket
}

func (w *wsresponse) ErrorWithMsg(errorCode ResCode, params ...interface{}) *[]byte {
	result := ResponseData{
		Success: false,
		Code:    errorCode,
		Msg:     params,
		Data:    nil,
	}
	rpacket, _ := json.Marshal(result)
	return &rpacket
}
